package com.unitd.base.module.consumer.comm.resolver;

import com.unitd.base.frame.spring.SpringContextProvider;
import com.unitd.base.module.consumer.comm.annotation.LoginUser;
import com.unitd.base.module.consumer.comm.interceptor.AuthorizationInterceptor;
import com.unitd.base.module.master.pojo.dto.UserVO;
import com.unitd.base.module.master.service.UserService;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * 有@LoginUser注解的方法参数，注入当前登录用户
 * HandlerMethodArgumentResolver用于统一获取当前登录用户
 *
 * @author hudan
 * @version 1.0
 * @filename LoginUserHandlerMethodArgumentResolver.java
 * @copyright www.unitd.com
 * @date 2020-07-05
 */
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     * 支持给请求参数赋予的参数
     *
     * @param parameter 请求参数
     * @return 自动赋予的参数
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(UserVO.class)
                && parameter.hasParameterAnnotation(LoginUser.class);
    }

    /**
     * 处理请求调用的参数
     *
     * @param parameter 实际请求业务参数
     * @param container 请求对应的控制器
     * @param request   web请求
     * @param factory   数据绑定工厂对象
     * @return 处理结果
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest request, WebDataBinderFactory factory) {
        // 获取用户ID
        Object object = request.getAttribute(AuthorizationInterceptor.LOGIN_USER_KEY, RequestAttributes.SCOPE_REQUEST);
        if (object == null) {
            return null;
        }

        // 获取用户信息
        UserService userService = SpringContextProvider.getBean(UserService.class);
        return userService.selectById((Long) object);
    }
}